package org.type4neo.imp;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.type4neo.TypedRelationship;
import org.type4neo.bytecode.DynamicTyper;

public class TypedRelationshipImp extends TypedPrimitiveImp implements TypedRelationship {
	public TypedRelationshipImp() {
	}
	
	/* (non-Javadoc)
	 * @see org.type4neo.TypedRelationship#getUnderlyingRelationship()
	 */
	public Relationship getUnderlyingRelationship() {
		return (Relationship) this.pc;
	}

	/* (non-Javadoc)
	 * @see org.type4neo.TypedRelationship#mutateTo(java.lang.Class)
	 */
	public Relationship mutateTo(Class<? extends TypedRelationship> newType) {
		if (newType == null || !newType.isInterface()) throw new IllegalArgumentException("Given new type must be an Instance class");
		this.pc.setProperty(DynamicTyper.PROTOTYPE_PROPERTY_NAME, newType.getName());
		return DynamicTyper.wrapRelationship((Relationship) this.pc);
	}

	public long getId() {
		return ((Relationship) this.pc).getId();
	}

	public void delete() {
		((Relationship) this.pc).delete();
	}

	public Node getStartNode() {
		return DynamicTyper.wrapNode(((Relationship) this.pc).getStartNode());
	}

	public Node getEndNode() {
		return DynamicTyper.wrapNode(((Relationship) this.pc).getEndNode());
	}

	public Node getOtherNode(Node node) {
		return DynamicTyper.wrapNode(((Relationship) this.pc).getOtherNode(node));
	}

	public Node[] getNodes() {
		Node[] temp = ((Relationship) this.pc).getNodes();
		if (temp == null) return null;
		Node[] resp = new Node[temp.length];
		for (int i = 0; i < temp.length; i++) {
			resp[i] = DynamicTyper.wrapNode(temp[i]);
		}
		return resp;
	}

	public RelationshipType getType() {
		return DynamicRelType.getType(this.getClass());
	}

	public boolean isType(RelationshipType type) {
		return this.getClass().getName().equals(type.name());
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof TypedRelationship) {
			return this.getId() == ((TypedRelationship) obj).getId();
		}
		return false;
	}

}
